package team.bluepen.supermarket.data.entity;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import space.lingu.light.DataColumn;
import space.lingu.light.DataTable;
import space.lingu.light.PrimaryKey;
import team.bluepen.supermarket.kafka.KafkaDeserializer;
import team.bluepen.supermarket.kafka.KafkaSerializer;

import java.beans.ConstructorProperties;
import java.io.Serializable;

/**
 * Count by product id.
 *
 * @author RollW
 */
@DataTable(name = "product_id_amount")
public class ProductIdAmount implements Serializable {
    @JsonProperty("id")
    @PrimaryKey
    @DataColumn(name = "id")
    private final Long id;

    @JsonProperty("amount")
    @DataColumn(name = "amount")
    private final int amount;

    @ConstructorProperties({"id",  "amount"})
    public ProductIdAmount(Long id, int amount) {
        this.id = id;
        this.amount = amount;
    }

    public Long getId() {
        return id;
    }

    public int getAmount() {
        return amount;
    }

    public static KafkaSerializer<ProductIdAmount> serializer() {
        return ProductIdAmount.Serial.INSTANCE;
    }

    public static KafkaDeserializer<ProductIdAmount> deserializer() {
        return ProductIdAmount.Serial.INSTANCE;
    }

    private static class Serial implements KafkaSerializer<ProductIdAmount>,
            KafkaDeserializer<ProductIdAmount> {
        private final ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public String serialize(ProductIdAmount productIdAmount) {
            try {
                return objectMapper.writeValueAsString(productIdAmount);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public ProductIdAmount deserialize(String s) {
            try {
                return objectMapper.readValue(s, ProductIdAmount.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }

        private static final ProductIdAmount.Serial INSTANCE = new ProductIdAmount.Serial();
    }
}
